package com.ll.sender;

import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ll.config.EmailServerConfiguration;
import com.ll.constants.EmailSendFailure;
import com.ll.exception.SendExecutionException;
import com.ll.exception.UserException;
import com.ll.exception.UserExceptionConstants;
import com.ll.service.EmailMessageHistoryService;
import com.ll.service.EmailMessageService;
import com.ll.vo.request.EmailMessageHistoryRequestVo;
import com.ll.vo.response.EmailMessageResponseVo;

/**
 * 线程池
 * 
 * @author liudawei
 * @date 2016年2月2日下午6:23:11
 */
@Service
public class EmailSenderThreadPool {

	private static Logger LOGGER = LoggerFactory.getLogger(EmailSenderThreadPool.class);

	private static int corePoolSize;
	private static int maximumPoolSize;

	private static EmailServerConfiguration emailServerConfiguration = new EmailServerConfiguration();

	@Autowired
	private EmailMessageService emailMessageService;
	@Autowired
	private EmailMessageHistoryService emailMessageHistoryService;

	static {
		corePoolSize = emailServerConfiguration.getSize("corePoolSize");
		maximumPoolSize = emailServerConfiguration.getSize("maximumPoolSize");
	}

	private static ExecutorService executorService = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 0L,
			TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());

	@PostConstruct
	public void init() {

		Executors.newSingleThreadExecutor().submit(new InitTask(emailMessageService, emailMessageHistoryService));

	}

	private static final class InitTask implements Runnable {
		private EmailMessageService emailMessageService;
		private EmailMessageHistoryService emailMessageHistoryService;

		public InitTask(EmailMessageService emailMessageService,
				EmailMessageHistoryService emailMessageHistoryService) {
			this.emailMessageService = emailMessageService;
			this.emailMessageHistoryService = emailMessageHistoryService;
		}

		@Override
		public void run() {
			while (true) {
				EmailSenderTask emailSenderTask = TaskQueue.takeData();
				if (emailSenderTask != null) {
					EmailMessageResponseVo emailMessageResponseVo = emailSenderTask.getEmailMessageResponseVo();
					EmailMessageHistoryRequestVo emailMessageHistoryRequestVo = new EmailMessageHistoryRequestVo();
					try {
						if (emailMessageResponseVo.getFireTimes() < emailServerConfiguration.getSize("fireTimes")) {
							Future future = executorService.submit(emailSenderTask);
							if (future.get() == null) {
									BeanUtils.copyProperties(emailMessageHistoryRequestVo, emailMessageResponseVo);
								emailMessageHistoryRequestVo.setResult(EmailSendFailure.SUEESS.ordinal());
								if (emailMessageHistoryRequestVo.getFailureReason() == null) {
									emailMessageHistoryRequestVo.setFailureReason("");
								}
								emailMessageHistoryService.saveEmailMessageHistory(emailMessageHistoryRequestVo);
								emailMessageService.deleteEmailMessage(emailMessageResponseVo.getId());
							} else {// 失败
								emailMessageService.unlockEmailMessage(emailMessageResponseVo.getId());
							}
						} else {
								BeanUtils.copyProperties(emailMessageHistoryRequestVo, emailMessageResponseVo);
							emailMessageHistoryRequestVo.setResult(EmailSendFailure.MAX.ordinal());
							emailMessageHistoryRequestVo.setFailureReason(EmailSendFailure.MAX.getName());
							emailMessageHistoryService.saveEmailMessageHistory(emailMessageHistoryRequestVo);
							emailMessageService.deleteEmailMessage(emailMessageResponseVo.getId());
						}
					} catch (InterruptedException e) {
						LOGGER.error("InterruptedException",e);
						emailMessageService.unlockEmailMessage(emailMessageResponseVo.getId());
					} catch (ExecutionException e) {
						LOGGER.error("ExecutionException",e);
						emailMessageService.unlockEmailMessage(emailMessageResponseVo.getId());
					} catch (SendExecutionException e) {
						emailMessageService.unlockEmailMessage(emailMessageResponseVo.getId());
						LOGGER.error("发送邮件失败", e);
						throw new UserException(UserExceptionConstants.SENDMESSAGINGEXCEPTION, e);
					} catch (IllegalAccessException e) {
						LOGGER.error("EmailMessageResponseVo对象和EmailMessageHistory对象在拷贝属性值的时候，抛出异常信息", e);
						throw new UserException(UserExceptionConstants.MAINTAINING, e);
					} catch (InvocationTargetException e) {
						LOGGER.error("EmailMessageResponseVo对象和EmailMessageHistory对象在拷贝属性值的时候，抛出异常信息", e);
						throw new UserException(UserExceptionConstants.MAINTAINING, e);
					}
				}
			}
		}

	}

}
